package com.hwj.controller;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.hwj.entity.Permission;
import com.hwj.entity.Role;
import com.hwj.entity.RolePermission;
import com.hwj.entity.User;
import com.hwj.service.PermissionService;
import com.hwj.service.RolePermissionService;
import com.hwj.service.RoleService;
import com.hwj.service.UserInfoService;
import com.hwj.utils.JsonResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@CrossOrigin
@RestController
@RequestMapping("/userinfo")
@Slf4j
public class UserInfoController {
    @Autowired
    UserInfoService userInfoService;
    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    RoleService roleService;
    @Autowired
    RolePermissionService rolePermissionService;
    @Autowired
    PermissionService permissionService;


    /*登陆*/
    @PostMapping("/login")
    public JsonResponse doLogin(@RequestBody User user){
        User user1=userInfoService.queryByName(user.getUsername());
        if(user1==null) {
            return JsonResponse.failResponse(-2,"未找到用户",null);
        }
        //密码匹配校验 bCryptPasswordEncoder
        boolean matches = bCryptPasswordEncoder.matches(user.getPassword(), user1.getPassword());
        if (!matches) {
            return JsonResponse.failResponse(-2,"密码错误",null);
        }
        UserDetails userDetails = userInfoService.loadUserByUsername(user1.getUsername());
        log.info("userDetails :" + userDetails);

        //这里因为是重重新定义了后端的登录的方法，所以我们这里的UserDetail对象需要自己处理
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

        HashSet<Permission> permissionSet = new HashSet<>();
        Long roleId= user1.getRoleId();
        // 根据roleId从role_permission表查询出所有的permissionId
        List<RolePermission> rolePermissions = rolePermissionService.queryByRoleId(roleId);
        for (RolePermission rolePermission : rolePermissions) {
            Long permissionId = rolePermission.getPermissionId();
            // 根据permissionId查询permission信息
            Permission permission = permissionService.selectByPrimaryKey(permissionId);
            permissionSet.add(permission);
        }

        log.info("permissionSet " + permissionSet);

        Role role = roleService.selectByPrimaryKey(user1.getRoleId());
        user1.setRoleDescribe(role.getRoleDescribe());
        // 对资源根据id进行排序
        LinkedHashSet<Permission> sortedSet = permissionSet.stream().sorted(Comparator.comparing(Permission::getPermissionId)).collect(Collectors.toCollection(LinkedHashSet::new));
        //设置当前用户的资源信息
        log.info("sortedSet: " + sortedSet);
        user1.setPermissions(sortedSet);


        //String token = JWT.create().setExpiresAt(DateUtil.offsetDay(new Date(), 1)).setAudience(user.getUserid()+"").setKey(SecureUtil.md5(user.getUserpass()).getBytes()).sign();
        String token = JWT.create().setExpiresAt(DateUtil.offsetDay(new Date(), 1)).setPayload("userId", user1.getUserId()).setKey(user1.getPassword().getBytes()).sign();
        //Algorithm.HMAC256(user.getPassword())

        user1.setToken(token);

        //测试security中的user
        log.info("security :" + SecurityContextHolder.getContext().getAuthentication());

        return JsonResponse.successResponse(0,"登陆成功",user1);
    }

    /*注册用户*/
    @PostMapping("/register")
    public JsonResponse register(@RequestBody(required = false) User user) {
        User user1 = userInfoService.queryByName(user.getUsername());
        if (user1 != null) {
            return JsonResponse.failResponse(-2, "该用户名已经被注册！",null);
        }
        user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
        String uuid=1000 +new Random().nextInt(9000)+"";
        user.setRealName("用户"+uuid);
        user.setProfile("我是一个特别喜欢宠物的一个人，希望大家与我交朋友~");
        user.setAvatar("https://img2.baidu.com/it/u=1504791015,2700524207&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500");
        userInfoService.insertSelective(user);
        return JsonResponse.successResponse(0,"注册成功！请重新登陆",null);
    }

    /*查询指定用户*/
    @GetMapping("/getInfo")
    public JsonResponse queryById(HttpServletRequest request){
        JWT jwt = JWTUtil.parseToken(request.getHeader("token"));
        Object userId = jwt.getPayload("userId");
        User user1=userInfoService.queryById(Long.parseLong(userId+""));
        HashSet<Permission> permissionSet = new HashSet<>();
        Long roleId= user1.getRoleId();
        // 根据roleId从role_permission表查询出所有的permissionId
        List<RolePermission> rolePermissions = rolePermissionService.queryByRoleId(roleId);
        for (RolePermission rolePermission : rolePermissions) {
            Long permissionId = rolePermission.getPermissionId();
            // 根据permissionId查询permission信息
            Permission permission = permissionService.selectByPrimaryKey(permissionId);
            permissionSet.add(permission);
        }

        log.info("permissionSet " + permissionSet);

        Role role = roleService.selectByPrimaryKey(user1.getRoleId());
        user1.setRoleDescribe(role.getRoleDescribe());
        // 对资源根据id进行排序
        LinkedHashSet<Permission> sortedSet = permissionSet.stream().sorted(Comparator.comparing(Permission::getPermissionId)).collect(Collectors.toCollection(LinkedHashSet::new));
        //设置当前用户的资源信息
        log.info("sortedSet: " + sortedSet);
        user1.setPermissions(sortedSet);


        //String token = JWT.create().setExpiresAt(DateUtil.offsetDay(new Date(), 1)).setAudience(user.getUserid()+"").setKey(SecureUtil.md5(user.getUserpass()).getBytes()).sign();
        String token = request.getHeader("token");
        //Algorithm.HMAC256(user.getPassword())

        user1.setToken(token);

        return JsonResponse.successResponse(0,"查询单个用户信息成功",user1);
    }

    /*分页查询*/
    @PostMapping("/page")
    public JsonResponse queryByPage(@RequestBody(required = false) User user, @RequestParam(value = "pageNum",required = false) Integer pageNum, @RequestParam(value = "pageSize",required = false) Integer pageSize){
        if(user==null){
            user=new User();
        }
        return JsonResponse.successResponse(0,"查询用户信息成功",userInfoService.queryByNamePhoneEmail(user,pageNum,pageSize));
    }

    /*删除*/
    @DeleteMapping("/{id}")
    public JsonResponse deleteById(@PathVariable Long id){
        return JsonResponse.successResponse(0,"删除成功",userInfoService.deleteByPrimaryKey(id));
    }

    /**
     * 更新和新增
     * @param user
     * @return
     */
    @PutMapping("/")
    public JsonResponse updateUser(@RequestBody User user) {
        if (user.getUserId() == null) {
            User user1 = userInfoService.queryByName(user.getUsername());
            if (user1 != null) {
                return JsonResponse.failResponse(-2, "该用户名已经存在！",null);
            }
            user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
            int i=userInfoService.insertSelective(user);
            if(i==1){
                return JsonResponse.successResponse(0,"新增用户信息成功",null);
            }else {
                return JsonResponse.failResponse(-2,"新增用户信息失败",null);
            }
        } else {
            //获取这个用户信息，方便接下的密码比对
            User user1=userInfoService.queryById(user.getUserId());
            if(StrUtil.isNotBlank(user.getPhone())&&!Validator.isMobile(user.getPhone())){
                return JsonResponse.failResponse(-2,"手机号格式错误",null);
            }
            if(StrUtil.isNotBlank(user.getEmail())&&!Validator.isEmail(user.getEmail())){
                return JsonResponse.failResponse(-2,"邮箱格式错误",null);
            }
            if(!user1.getPassword().equals(user.getPassword())){
                //数据加密
                user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
            }

            int i=userInfoService.updateByPrimaryKeySelective(user);
            if(i==1) {
                return JsonResponse.successResponse(0, "更新用户信息成功", null);
            }
            return JsonResponse.failResponse(-2,"更新用户信息失败",null);
        }
    }

    @PutMapping("changeRole/{user_id}/{role_id}")
    public JsonResponse changeRole(@PathVariable(name = "user_id") Long user_id,@PathVariable(name = "role_id") Long role_id){
        User user=new User();
        user.setUserId(user_id);
        user.setRoleId(role_id);
        int i=userInfoService.updateByPrimaryKeySelective(user);
        if(i==1) {
            return JsonResponse.successResponse(0, "变更角色成功", null);
        }
        return JsonResponse.failResponse(-2,"变更角色失败",null);
    }


    @PostMapping("/password")
    public JsonResponse updatePassword(@RequestBody Map<String,String> passwordEntity,HttpServletRequest request){
        String oldPassword=passwordEntity.get("oldPassword");
        String newPassword=passwordEntity.get("newPassword");
        if(StrUtil.isBlank(oldPassword)||StrUtil.isBlank(newPassword)){
            JsonResponse.failResponse(-2,"传入参数有误",null);
        }
        JWT jwt = JWTUtil.parseToken(request.getHeader("token"));
        Object userId = jwt.getPayload("userId");
        User user=userInfoService.queryById(Long.parseLong(userId+""));
        //密码匹配校验 bCryptPasswordEncoder
        boolean matches = bCryptPasswordEncoder.matches(oldPassword,user.getPassword());
        if(!matches){
            return JsonResponse.failResponse(-2,"旧密码输入错误，请重新输入",null);
        }
        if(oldPassword.equals(newPassword)){
            return JsonResponse.failResponse(-2,"新密码不能与旧密码一致",null);
        }
        user.setPassword(new BCryptPasswordEncoder().encode(newPassword));
        userInfoService.updateByPrimaryKeySelective(user);
        return JsonResponse.successResponse(0,"修改密码成功",null);
    }

    /**
     * 查询优秀作者前十
     * @return
     */
    @GetMapping("/excellent")
    public JsonResponse getExcellentUser(){
        return JsonResponse.successResponse(0,"查询优秀作者成功",userInfoService.getExcellentUser());
    }

}
